﻿using FriendAnalyzer.Infrastructure.Facebook.DataAccess;
using FriendAnalyzer.Infrastructure.Facebook.Interfaces;
using FriendAnalyzer.Infrastructure.Facebook.Model;
using FriendAnalyzer.Infrastructure.Facebook.Model.Enums;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FriendAnalyzer.Infrastructure.Facebook.Repositories
{
    internal class FriendRepository : IFriendRepository
    {
        private FacebookConnection _connection;

        public FriendRepository(FacebookConnection connection)
        {
            _connection = connection;
        }

        public async Task<List<FacebookUser>> GetFacebookFriendsAsync()
        {
            var fql = @"SELECT uid, first_name, last_name, pic_square, sex FROM user
                        WHERE uid IN
                        (SELECT uid1 FROM friend WHERE uid2 = me()) LIMIT 100";

            var friends = await _connection.ExecuteQueryAsync<Profile>(fql);

            var result = from friend in friends
                         select new FacebookUser
                         {
                             FirstName = friend.FirstName,
                             LastName = friend.LastName,
                             UserID = friend.UserID,
                             PictureUrl = friend.PictureUrl,
                             Gender = GetGender(friend.Gender),
                         };

            return result.ToList();
        }
        public async Task<List<FacebookEvent>> GetAllFriendEventsAsync()
        {
            var fql = @"SELECT uid, eid FROM event_member 
                        WHERE uid IN
                        (SELECT uid2 FROM friend WHERE uid1 = me())";

            var events = await _connection.ExecuteQueryAsync<EventAttended>(fql);

            var result = from evt in events
                         select new FacebookEvent
                         {
                             EventID = evt.EventID,
                             AttendedBy = evt.UserID,
                         };

            return result.ToList();
        }
        public async Task<List<FacebookLike>> GetAllPageLikesAsync()
        {
            var fql = @"SELECT page_id, uid FROM page_fan
                        WHERE uid IN
                        (SELECT uid2 FROM friend WHERE uid1 = me())";

            var likes = await _connection.ExecuteQueryAsync<PageLike>(fql);

            var result = from like in likes
                         select new FacebookLike
                         {
                             LikedID = like.PageID,
                             LikedBy = like.UserID,
                             LikeType = LikeType.Page
                         };

            return result.ToList();
        }
        public async Task<List<FacebookCheckin>> GetAllCheckinsAsync()
        {
            var fql = @"SELECT author_uid, id FROM location_post 
                        WHERE author_uid IN 
                        (SELECT uid2 FROM friend WHERE uid1 = me())";

            var checkins = await _connection.ExecuteQueryAsync<CheckIn>(fql);

            var result = from checkin in checkins
                         select new FacebookCheckin
                         {
                             LocationID = checkin.LocationID,
                             UserID = checkin.TaggedPerson,
                         };

            return result.ToList();
        }
        public async Task<List<FacebookGroup>> GetAllGroupsAsync()
        {
            var fql = @"SELECT gid, uid FROM group_member
                        WHERE uid IN 
                        (SELECT uid2 FROM friend WHERE uid1 = me())";

            var likes = await _connection.ExecuteQueryAsync<Group>(fql);

            var result = from like in likes
                         select new FacebookGroup
                         {
                             GroupID = like.GroupID,
                             MemberID = like.MemberID,
                         };

            return result.ToList();
        }

        private Gender GetGender(string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                if (value.ToLower() == Gender.Male.ToString().ToLower())
                {
                    return Gender.Male;
                }
                else
                {
                    return Gender.Female;
                }
            }
            else
            {
                return Gender.Unknown;
            }
        }
    }
}
